<template>
  <view class="chat-container">
    <!-- 消息列表 -->
    <scroll-view class="message-list" scroll-y="true" :scroll-top="scrollTop">
      <!-- 欢迎消息 -->
      <view class="message-item bot-message" :key="'welcome'">
        <image class="message-avatar" src="/static/a.gif" mode="aspectFill" alt="AI头像" />
        <view class="message-content">
          <view class="message-bubble">
            <text>你好！我是你的智能助手，有什么可以帮助你的吗？</text>
          </view>
        </view>
      </view>

      <!-- 循环渲染消息 -->
      <view
        v-for="(item, index) in messageList"
        :key="index"
        :class="['message-item', item.type === 'user' ? 'user-message' : 'bot-message']"
      >
        <!-- 头像 -->
        <image
          v-if="item.type === 'bot'"
          class="message-avatar"
          src="/static/a.gif"
          mode="aspectFill"
          alt="AI头像"
        />
        <image
          v-if="item.type === 'user'"
          class="message-avatar"
          src="/static/OIP.jpg"
          mode="aspectFill"
          alt="用户头像"
        />

        <!-- 内容 -->
        <view class="message-content">
          <view class="message-bubble">
            <!-- 如果是用户消息，就直接输出纯文本 -->
            <template v-if="item.type === 'user'">
              <text>{{ item.content }}</text>
            </template>

            <!-- 如果是机器人消息 -->
            <template v-else>
              <!-- 文件类型消息 -->
              <template v-if="item.contentType === 'file'">
                <view class="file-message" @click="previewFile(item)">
                  <image 
                    :src="getFileIcon(item.fileType)" 
                    class="file-icon" 
                    mode="aspectFit" 
                    alt="文件图标" 
                  />
                  <view class="file-info">
                    <text class="file-name">{{ item.fileType }}</text>
                    <text class="file-action">点击预览</text>
                  </view>
                </view>
              </template>
              
              <!-- 普通文本消息 -->
              <template v-else>
                <!-- H5/APP 下，使用 v-html -->
                <view
                  v-if="isWeb"
                  class="markdown-container"
                  v-html="item.html"
                ></view>

                <!-- 各端小程序下，使用 <rich-text> 渲染 HTML 字符串 -->
                <rich-text
                  v-else
                  :nodes="item.nodes"
                  class="markdown-container"
                ></rich-text>
              </template>
            </template>
          </view>
        </view>
      </view>

      <!-- 加载中状态 -->
      <view v-if="isLoading" class="message-item bot-message" :key="'loading'">
        <image class="message-avatar" src="/static/a.gif" mode="aspectFill" alt="AI头像" />
        <view class="message-content">
          <view class="message-bubble loading-bubble">
            <text>思考中</text>
            <view class="loading-dots">
              <view class="dot"></view>
              <view class="dot"></view>
              <view class="dot"></view>
            </view>
          </view>
        </view>
      </view>
    </scroll-view>

    <!-- 输入区域 -->
    <view class="input-area">
      <textarea
        v-model="inputText"
        class="input-field"
        placeholder="请输入问题..."
        :auto-height="true"
        :max-height="100"
        :confirm-type="'send'"
        @confirm="sendMessage"
      ></textarea>
      
      <!-- 发送按钮 -->
      <view
        class="send-btn"
        @click="sendMessage"
      >
        <uni-icons type="paperplane" size="24" color="#fff" />
      </view>
    </view>
  </view>
</template>

<script setup>
import { ref, computed, onMounted } from 'vue'

const userInfo = uni.getStorageSync("userInfo")

// 引入 markdown-it
import MarkdownIt from 'markdown-it'

const md = new MarkdownIt()

// 简单的"把 HTML 转成 rich-text nodes"示例函数
function useHtml2nodes(htmlStr) {
  let nodes = []
  try {
    nodes = uni.$u.html2json(htmlStr, {}).nodes
  } catch (e) {
    nodes = [{ name: 'text', attrs: {}, children: [{ type: 'text', text: htmlStr }] }]
  }
  return nodes
}

// 数据定义
const messageList = ref([])
const inputText = ref('')
const isLoading = ref(false)
const scrollTop = ref(0)
const errorMsg = ref('')

const isWeb = computed(() => {
  // #ifdef H5 || APP-PLUS
  return true
  // #endif
  // #ifdef MP-WEIXIN || MP-ALIPAY || MP-BAIDU || MP-TOUTIAO || MP-QQ
  return false
  // #endif
})

// 获取文件图标
const getFileIcon = (fileType) => {
  // 根据文件后缀返回对应的图标路径
  if (fileType === '图纸') {
    return '/static/PDF.png' // 需要准备PDF图标
  } else if (fileType === '结算表') {
    return '/static/xlsx.png' // 需要准备Excel图标
  } else {
    return '/static/file.png' // 通用文件图标
  }
}

// 预览文件
const previewFile = (item) => {
  const url = `./api/preview/${item.uuid}/${item.filename}`;
  
  // #ifdef H5
  // H5平台直接打开URL
  window.open(url, '_blank');
  // #endif
  
  // #ifdef APP-PLUS
  // APP平台下载并打开文件
  uni.showLoading({ title: '文件加载中...', mask: true });
  uni.downloadFile({
    url,
	headers: {
	  "Authorization": `Bearer ${userInfo.token}`,
	},
    success: (res) => {
      if (res.statusCode === 200) {
        uni.openDocument({
          filePath: res.tempFilePath,
          success: () => {
            // console.log('文件打开成功');
          },
          fail: (err) => {
            console.error('文件打开失败', err);
            uni.showToast({
              title: '文件预览失败，请重试',
              icon: 'none'
            });
          }
        });
      } else {
        console.error('下载文件失败，状态码:', res.statusCode, '响应数据:', res.data);
        uni.showToast({
          title: '文件下载失败，请重试',
          icon: 'none'
        });
      }
    },
    fail: (err) => {
      console.error('下载请求失败', err);
      uni.showToast({
        title: '网络请求失败，请检查网络',
        icon: 'none'
      });
    },
    complete: () => {
      // 无论成功/失败都关闭加载提示
      uni.hideLoading();
    }
  });
  // #endif
  
  // #ifdef MP-WEIXIN || MP-ALIPAY || MP-BAIDU || MP-TOUTIAO || MP-QQ
  // 小程序平台：添加加载提示优化体验
  uni.showLoading({ title: '文件加载中...', mask: true });
  uni.downloadFile({
    url,
	headers: {
	  "Authorization": `Bearer ${userInfo.token}`,
	},
    success: (res) => {
      if (res.statusCode === 200) {
        uni.openDocument({
          filePath: res.tempFilePath,
          success: () => {
            // console.log('文件打开成功');
          },
          fail: (err) => {
            console.error('文件打开失败', err);
            uni.showToast({
              title: '文件预览失败，请重试',
              icon: 'none'
            });
          }
        });
      } else {
        console.error('下载文件失败，状态码:', res.statusCode, '响应数据:', res.data);
        uni.showToast({
          title: '文件下载失败，请重试',
          icon: 'none'
        });
      }
    },
    fail: (err) => {
      console.error('下载请求失败', err);
      uni.showToast({
        title: '网络请求失败，请检查网络',
        icon: 'none'
      });
    },
    complete: () => {
      // 无论成功/失败都关闭加载提示
      uni.hideLoading();
    }
  });
  // #endif
};

onMounted(() => {
  setTimeout(() => {
    scrollTop.value = 9999
  }, 100)
})

// 发送消息
const sendMessage = () => {
  const content = inputText.value.trim()
  if (!content) return

  messageList.value.push({ type: 'user', content })
  inputText.value = ''

  scrollTop.value = 9999
  isLoading.value = true
  errorMsg.value = ''

  uni.request({
    url: './api/agent',
    method: 'POST',
    data: { message: content },
    header: { 
		'Content-Type': 'application/json',
		"Authorization": `Bearer ${userInfo.token}`,
		
	},
    success: (res) => {
      if (res.statusCode === 200 && res.data) {
        const isFileResponse = 
          (res.data.type === 'file' && res.data.uuid && res.data.filename) || // 单文件
          (Array.isArray(res.data) && res.data.every(item => item.type === 'file')) // 多文件

        if (isFileResponse) {
          const fileList = Array.isArray(res.data) ? res.data : [res.data]
          fileList.forEach(item => {
            if (item.filetype != "其他") { 
              messageList.value.push({
                type: 'bot',
                contentType: 'file',
                fileType: item.filetype,
                uuid: item.uuid,
                filename: item.filename,
                content: `已生成文件：${item.filename}`
              })
            }
          })
        } 

        else if (res.data.answer) { 
          const mdText = res.data.answer
          const html = md.render(mdText)
          const nodes = !isWeb.value ? useHtml2nodes(html) : []
          messageList.value.push({ type: 'bot', content: mdText, html, nodes })
        } 
        else {
          errorMsg.value = '服务器响应格式错误'
          console.error('API错误: 响应格式不符合预期', res)
        }
      } else {
        errorMsg.value = '服务器响应异常'
        console.error('API错误:', res)
        const mdText = '服务器响应异常'
        const html = md.render(mdText)
        const nodes = !isWeb.value ? useHtml2nodes(html) : []
        messageList.value.push({ type: 'bot', content: mdText, html, nodes })
      }
    },
    fail: (err) => {
      errorMsg.value = '网络请求失败，请检查网络连接'
      console.error('请求错误:', err)
    },
    complete: () => {
      // 隐藏加载状态
      isLoading.value = false
      // 滚动到底部
      scrollTop.value = 9999
    }
  })
}
</script>

<style scoped>
	* {
  box-sizing: border-box;
}
.chat-container {
  display: flex;
  flex-direction: column;
  height: 90vh;
  background-color: #f5f5f5;
  position: relative;
}

.message-list {
  flex: 1;
  padding: 15px;
  overflow-y: auto;
  padding-bottom: 80px;
}

.message-item {
  display: flex;
  margin-bottom: 15px;
  max-width: 100%;
}

.user-message {
  flex-direction: row-reverse;
}

.message-avatar {
  width: 46px;
  height: 46px;
  border-radius: 50%;
  margin: 0 10px;
}

.message-content {
  max-width: 75%;
}

.message-bubble {
  position: relative;
  padding: 10px 15px;
  border-radius: 18px;
  font-size: 16px;
  line-height: 1.5;
  white-space: pre-wrap; 
  word-break: break-word;
}

.user-message .message-bubble {
  background-color: #409eff;
  color: #ffffff;
}

.bot-message .message-bubble {
  background-color: #ffffff;
  color: #333333;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

.loading-bubble {
  padding: 10px 15px 15px 15px !important;
}

.loading-dots {
  display: flex;
  justify-content: center;
  margin-top: 5px;
}

.dot {
  width: 5px;
  height: 5px;
  background-color: #333333;
  border-radius: 50%;
  margin: 0 2px;
  animation: dotPulse 1.4s infinite ease-in-out both;
}

.dot:nth-child(1) {
  animation-delay: -0.32s;
}
.dot:nth-child(2) {
  animation-delay: -0.16s;
}

@keyframes dotPulse {
  0%,
  80%,
  100% {
    transform: scale(0);
  }
  40% {
    transform: scale(1);
  }
}

.input-area {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
  padding: 15px;
  background-color: #ffffff;
  box-shadow: 0 -2px 4px rgba(0, 0, 0, 0.05);
  z-index: 100;
}

.input-field {
  flex: 1;
  min-height: 40px;
  max-height: 100px;
  padding: 10px 15px;
  border-radius: 20px;
  background-color: #f5f5f5;
  font-size: 16px;
  line-height: 1.5;
  margin-right: 10px;
}

/* 发送按钮样式 */
.send-btn {
  width: 44px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(90deg, #409eff, #66b1ff);
  border-radius: 20px;
  transition: background-color 0.2s, transform 0.1s;
  flex-shrink: 0;
  
  &:active {
    transform: scale(0.98);
  }
}

.error-message {
  color: #f56c6c;
  text-align: center;
  padding: 10px;
}

.markdown-container {
  word-wrap: break-word;
  white-space: normal;
}

.markdown-container h1 {
  font-size: 24px;
  margin: 10px 0;
  font-weight: bold;
}
.markdown-container h2 {
  font-size: 20px;
  margin: 8px 0;
  font-weight: bold;
}
.markdown-container h3 {
  font-size: 18px;
  margin: 6px 0;
  font-weight: bold;
}
.markdown-container strong {
  font-weight: bold;
}
.markdown-container em {
  font-style: italic;
}
.markdown-container ul,
.markdown-container ol {
  padding-left: 20px;
  margin: 8px 0;
}
.markdown-container li {
  margin: 4px 0;
}
.markdown-container pre {
  background-color: #f0f0f0;
  padding: 8px;
  border-radius: 4px;
  overflow-x: auto;
  margin: 8px 0;
}
.markdown-container code {
  background-color: #f5f5f5;
  padding: 2px 4px;
  border-radius: 4px;
}
.markdown-container a {
  color: #409eff;
  text-decoration: underline;
}
.markdown-container blockquote {
  border-left: 3px solid #ccc;
  padding-left: 10px;
  color: #666;
  margin: 8px 0;
}

/* 文件消息样式 */
.file-message {
  display: flex;
  align-items: center;
  padding: 10px;
  border: 1px solid #e4e7ed;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.3s;
}

.file-message:hover {
  background-color: #f5f7fa;
}

.file-icon {
  width: 40px;
  height: 40px;
  margin-right: 10px;
}

.file-info {
  flex: 1;
  min-width: 0;
}

.file-name {
  display: block;
  font-size: 14px;
  color: #303133;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.file-action {
  display: block;
  font-size: 12px;
  color: #409eff;
  margin-top: 2px;
}
</style>